<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>执行器运行情况监控</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background-color: #f5f5f5;
            color: #333;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 10px;
            margin-bottom: 20px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .overview-cards {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }

        .card {
            background: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            transition: transform 0.3s ease;
        }

        .card:hover {
            transform: translateY(-5px);
        }

        .card-header {
            display: flex;
            align-items: center;
            margin-bottom: 15px;
        }

        .card-icon {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 15px;
            font-size: 1.5em;
        }

        .card-title {
            font-size: 1.1em;
            font-weight: bold;
            color: #555;
        }

        .card-value {
            font-size: 2em;
            font-weight: bold;
            margin-bottom: 5px;
        }

        .card-subtitle {
            color: #888;
            font-size: 0.9em;
        }

        .status-online { background-color: #4CAF50; color: white; }
        .status-offline { background-color: #f44336; color: white; }
        .status-healthy { background-color: #4CAF50; color: white; }
        .status-warning { background-color: #ff9800; color: white; }
        .status-error { background-color: #f44336; color: white; }

        .executors-table {
            background: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
        }

        .table-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        .table-title {
            font-size: 1.5em;
            font-weight: bold;
            color: #333;
        }

        .refresh-btn {
            background: #667eea;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 1em;
            transition: background-color 0.3s ease;
        }

        .refresh-btn:hover {
            background: #5a6fd8;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        th, td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #eee;
        }

        th {
            background-color: #f8f9fa;
            font-weight: bold;
            color: #555;
        }

        tr:hover {
            background-color: #f8f9fa;
        }

        .status-badge {
            padding: 4px 8px;
            border-radius: 12px;
            font-size: 0.8em;
            font-weight: bold;
        }

        .progress-bar {
            width: 100%;
            height: 8px;
            background-color: #e0e0e0;
            border-radius: 4px;
            overflow: hidden;
        }

        .progress-fill {
            height: 100%;
            border-radius: 4px;
            transition: width 0.3s ease;
        }

        .progress-low { background-color: #4CAF50; }
        .progress-medium { background-color: #ff9800; }
        .progress-high { background-color: #f44336; }

        .loading {
            text-align: center;
            padding: 40px;
            color: #666;
        }

        .error {
            background: #ffebee;
            color: #c62828;
            padding: 15px;
            border-radius: 5px;
            margin: 10px 0;
        }

        @media (max-width: 768px) {
            .overview-cards {
                grid-template-columns: 1fr;
            }
            
            .container {
                padding: 10px;
            }
            
            table {
                font-size: 0.9em;
            }
            
            th, td {
                padding: 8px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>执行器运行情况监控</h1>
            <p>实时监控执行器状态、资源使用情况和健康状态</p>
        </div>

        <div class="overview-cards" id="overviewCards">
            <div class="loading">加载中...</div>
        </div>

        <div class="executors-table">
            <div class="table-header">
                <h2 class="table-title">执行器列表</h2>
                <button class="refresh-btn" onclick="loadData()">刷新数据</button>
            </div>
            <div id="executorsTable">
                <div class="loading">加载中...</div>
            </div>
        </div>
    </div>

    <script>
        // API基础URL
        const API_BASE = '/api/executor-runtime';
        
        // 页面加载时获取数据
        document.addEventListener('DOMContentLoaded', function() {
            loadData();
        });

        // 加载数据
        async function loadData() {
            try {
                await Promise.all([
                    loadOverview(),
                    loadExecutors()
                ]);
            } catch (error) {
                console.error('加载数据失败:', error);
                showError('加载数据失败: ' + error.message);
            }
        }

        // 加载概览数据
        async function loadOverview() {
            const response = await fetch(`${API_BASE}/overview`);
            const result = await response.json();
            
            if (result.code === 200) {
                displayOverview(result.data);
            } else {
                throw new Error(result.message);
            }
        }

        // 加载执行器列表
        async function loadExecutors() {
            const response = await fetch(`${API_BASE}/all`);
            const result = await response.json();
            
            if (result.code === 200) {
                displayExecutors(result.data);
            } else {
                throw new Error(result.message);
            }
        }

        // 显示概览数据
        function displayOverview(data) {
            const overviewCards = document.getElementById('overviewCards');
            
            overviewCards.innerHTML = `
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon status-online">📊</div>
                        <div class="card-title">总执行器数</div>
                    </div>
                    <div class="card-value">${data.totalExecutors || 0}</div>
                    <div class="card-subtitle">注册的执行器总数</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon status-online">🟢</div>
                        <div class="card-title">在线执行器</div>
                    </div>
                    <div class="card-value">${data.onlineExecutors || 0}</div>
                    <div class="card-subtitle">当前在线执行器数量</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon status-healthy">💚</div>
                        <div class="card-title">健康执行器</div>
                    </div>
                    <div class="card-value">${data.healthyExecutors || 0}</div>
                    <div class="card-subtitle">运行正常的执行器</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon status-warning">⚠️</div>
                        <div class="card-title">警告执行器</div>
                    </div>
                    <div class="card-value">${data.warningExecutors || 0}</div>
                    <div class="card-subtitle">资源使用率较高的执行器</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon status-error">🔴</div>
                        <div class="card-title">异常执行器</div>
                    </div>
                    <div class="card-value">${data.errorExecutors || 0}</div>
                    <div class="card-subtitle">资源使用率过高或离线的执行器</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon" style="background-color: #2196F3; color: white;">⚡</div>
                        <div class="card-title">活跃线程数</div>
                    </div>
                    <div class="card-value">${data.totalActiveThreads || 0}</div>
                    <div class="card-subtitle">所有执行器的活跃线程总数</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon" style="background-color: #9C27B0; color: white;">🔄</div>
                        <div class="card-title">运行任务数</div>
                    </div>
                    <div class="card-value">${data.totalRunningTasks || 0}</div>
                    <div class="card-subtitle">当前正在执行的任务数量</div>
                </div>
                
                <div class="card">
                    <div class="card-header">
                        <div class="card-icon" style="background-color: #FF5722; color: white;">💾</div>
                        <div class="card-title">平均内存使用率</div>
                    </div>
                    <div class="card-value">${(data.averageMemoryUsage || 0).toFixed(1)}%</div>
                    <div class="card-subtitle">所有执行器的平均内存使用率</div>
                </div>
            `;
        }

        // 显示执行器列表
        function displayExecutors(executors) {
            const executorsTable = document.getElementById('executorsTable');
            
            if (!executors || executors.length === 0) {
                executorsTable.innerHTML = '<div class="loading">暂无执行器数据</div>';
                return;
            }

            const tableHTML = `
                <table>
                    <thead>
                        <tr>
                            <th>执行器标识</th>
                            <th>应用名称</th>
                            <th>状态</th>
                            <th>健康状态</th>
                            <th>活跃线程数</th>
                            <th>运行任务数</th>
                            <th>内存使用率</th>
                            <th>最后心跳时间</th>
                        </tr>
                    </thead>
                    <tbody>
                        ${executors.map(executor => `
                            <tr>
                                <td>${executor.registerKey || '-'}</td>
                                <td>${executor.appName || '-'}</td>
                                <td>
                                    <span class="status-badge ${executor.isOnline ? 'status-online' : 'status-offline'}">
                                        ${executor.statusDesc || '未知'}
                                    </span>
                                </td>
                                <td>
                                    <span class="status-badge ${getHealthStatusClass(executor.healthStatus)}">
                                        ${executor.healthStatus || '未知'}
                                    </span>
                                </td>
                                <td>${executor.currentActiveCount || 0}</td>
                                <td>${executor.currentRunningTasks || 0}</td>
                                <td>
                                    <div style="display: flex; align-items: center; gap: 10px;">
                                        <span>${(executor.currentMemoryUsagePercent || 0).toFixed(1)}%</span>
                                        <div class="progress-bar">
                                            <div class="progress-fill ${getProgressClass(executor.currentMemoryUsagePercent)}" 
                                                 style="width: ${executor.currentMemoryUsagePercent || 0}%"></div>
                                        </div>
                                    </div>
                                </td>
                                <td>${formatDateTime(executor.lastHeartbeatTime)}</td>
                            </tr>
                        `).join('')}
                    </tbody>
                </table>
            `;
            
            executorsTable.innerHTML = tableHTML;
        }

        // 获取健康状态样式类
        function getHealthStatusClass(healthStatus) {
            switch (healthStatus) {
                case '健康': return 'status-healthy';
                case '警告': return 'status-warning';
                case '异常': return 'status-error';
                default: return '';
            }
        }

        // 获取进度条样式类
        function getProgressClass(percentage) {
            if (percentage >= 80) return 'progress-high';
            if (percentage >= 60) return 'progress-medium';
            return 'progress-low';
        }

        // 格式化日期时间
        function formatDateTime(dateTimeStr) {
            if (!dateTimeStr) return '-';
            const date = new Date(dateTimeStr);
            return date.toLocaleString('zh-CN');
        }

        // 显示错误信息
        function showError(message) {
            const errorDiv = document.createElement('div');
            errorDiv.className = 'error';
            errorDiv.textContent = message;
            
            const container = document.querySelector('.container');
            container.insertBefore(errorDiv, container.firstChild);
            
            // 5秒后自动移除错误信息
            setTimeout(() => {
                errorDiv.remove();
            }, 5000);
        }

        // 定时刷新数据（每30秒）
        setInterval(loadData, 30000);
    </script>
</body>
</html>
